import { useContext } from "react";
import {
  clsx,
  get,
  getDeepth,
  shouldUpdate,
  toLevelPath,
  wrapperCls,
} from "../utils";
import RuleList from "./RuleList";
import { RuleTreeContext, RuleTreePropsContext } from "./RuleTreeContext";
import { useOutterComponents } from "../utils/hooks";
import type { FieldNames } from "../types";
import { fieldNamesTreeMap } from "../utils/global";
import RelationNode from "./RelationNode";
import styled from "styled-components";

const Wrapper = styled.div`
  display: flex;
  align-items: center;
`;

function RuleNode<T>(props: {
  path: (string | number)[];
  /** 其实就是list的索引，为null是因为root层不存在，做判断使用 */
  name: number | null;
  isRoot?: boolean;
}) {
  const { prefixCls } = useContext(RuleTreeContext);
  const { uid, nodeRender } = useContext(RuleTreePropsContext);
  const { Form } = useOutterComponents();
  const form = Form.useFormInstance();
  const cls = wrapperCls(prefixCls);
  const { children: ChildrenKey } = fieldNamesTreeMap.get(
    uid
  ) as Required<FieldNames>;

  const getFields = () => ({
    levelPath: toLevelPath(props.path),
    count: form.getFieldValue([...props.path, ChildrenKey])?.length || 0,
    deepth: getDeepth(props.path),
    index: props.name || 0,
  });

  const relationDom = <RelationNode name={props.name} path={props.path} />;
  const listDom = (
    <RuleList<T>
      path={[...props.path, ChildrenKey]}
      name={props.isRoot ? null : props.name}
    />
  );

  return (
    <Wrapper
      className={clsx(`${cls}-node`, { [`${cls}-node-root`]: props.isRoot })}
    >
      <Form.Item
        shouldUpdate={(prev, next) => {
          // nodeRender不存在，则不需要触发渲染
          if (!nodeRender) {
            return false;
          }

          const objA: any = get(prev, props.path) || {};
          const objB: any = get(next, props.path) || {};

          return shouldUpdate(objA, objB, ChildrenKey);
        }}
        noStyle
      >
        {() => {
          if (nodeRender) {
            return nodeRender({ relationDom, listDom }, getFields());
          }
          return (
            <>
              {relationDom}
              {listDom}
            </>
          );
        }}
      </Form.Item>
      {/* // TODO */}
      {/* {
        resultRender && (
          <div className={clsx(`${cls}-result`)} style={{ marginLeft: (gap as [number, number])[0] }}>
            <Form.Item noStyle name={[...props.path, 'result']}>
              {resultRender()}
            </Form.Item>
          </div>
        )
      } */}
    </Wrapper>
  );
}

export default RuleNode;
